package com.ifp.opengate.boot.gateway.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;

import com.ifp.core.exception.BaseException;
import com.ifp.opengate.boot.task.AccessCacheDataSyncTask;

/**
 * @Classname FilterAspect
 * @Description TODO
 * @Date 2019/7/5 15:40
 * @Created by zzh
 *          <p>
 *          zhuzh@belink.com
 *          </p>
 * @Version 1.0
 */
// @Component
@Aspect
public class FilterAspect {

    @Autowired
    private AccessCacheDataSyncTask accessCacheDataSyncHandler;

    @Pointcut("execution(* filter(..))&& target(org.springframework.cloud.gateway.filter.GlobalFilter)||target(org.springframework.cloud.gateway.filter.GatewayFilter)")
    public void filterPointCut() {}

    @Pointcut("execution(* org.springframework.cloud.gateway.filter.NettyRoutingFilter.filter(..))")
    public void routeFilterPointCut() {}

    @Before("filterPointCut()")
    public void beforeGetServicePointCut(JoinPoint joinPoint) throws Throwable {
        // if (!Cat.isInitialized()) {
        // return;
        // }
        // if (joinPoint.getArgs()[0] instanceof ServerWebExchange) {
        // Object target = joinPoint.getTarget();
        // ServerWebExchange exchange = (ServerWebExchange) joinPoint.getArgs()[0];
        // boolean isStatistics = (boolean) exchange.getAttributes().getOrDefault(Constants.ISSTATISTICS, true);
        // if (isStatistics) {
        // List<CatTransation> transations = (List<CatTransation>)
        // exchange.getAttributes().get(Constants.CAT_TRANSACTION);
        // Map map = (Map) exchange.getAttributes().get("cachedRequestBodyObject");
        // String apiId = RequestUtil.getActionId(exchange.getRequest());
        // if (null == transations || transations.isEmpty()) {
        // CatTransation httpTransation = new CatTransation();
        // httpTransation.setTransationName("Http");
        // httpTransation.setDesc(getTransaction(apiId, map));
        // httpTransation.setStatus("0");
        // transations = new ArrayList<>();
        // transations.add(httpTransation);
        // exchange.getAttributes().put(Constants.CAT_TRANSACTION, transations);
        // }
        // Route attribute = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        // CatTransation transation = new CatTransation();
        // transation.setTransationName("Filter");
        // transation.setDesc(target.toString());
        // transation.setStatus("0");
        // Map<String, String> events = new LinkedHashMap<>();
        // events.put("Filter.RouteInfo", attribute.toString());
        // events.put("Filter.Body", JSON.toJSONString(map));
        // transation.setEvents(events);
        // transations.add(transation);
        // }
        // }
    }

    @AfterThrowing(value = "filterPointCut()", throwing = "ex")
    public void throwExceptionPointCut(JoinPoint joinPoint, Throwable ex) {
        // if (joinPoint.getArgs()[0] instanceof ServerWebExchange) {
        // ServerWebExchange exchange = (ServerWebExchange) joinPoint.getArgs()[0];
        // List<CatTransation> transactions = (List<CatTransation>)
        // exchange.getAttributes().get(Constants.CAT_TRANSACTION);
        // if (null != transactions && !transactions.isEmpty() &&
        // !joinPoint.getTarget().toString().contains("EndRoutingFilter")) {
        // String logId = (String) exchange.getAttributes().get(com.ifp.openapi.common.Constants.GLOBALLOGID);
        // Cat.getProducer().setCustomizeMsgId(logId.substring(logId.lastIndexOf("-") + 1));
        // CatTransation httpCatTranstion = transactions.remove(0);
        // Transaction httpTransaction = Cat.getProducer().newTransaction(httpCatTranstion.getTransationName(),
        // httpCatTranstion.getDesc());
        // httpTransaction.setStatus(ex);
        // Transaction transaction = Cat.getProducer().newTransaction("Http.Info", logId);
        // transaction.setStatus(ex);
        // transaction.complete();
        // for (CatTransation transation : transactions) {
        // Transaction tsn = Cat.newTransaction(transation.getTransationName(), transation.getDesc());
        // tsn.setStatus(transation.getStatus());
        // Map<String, String> events = transation.getEvents();
        // for (Map.Entry<String, String> event : events.entrySet()) {
        // Cat.logEvent(event.getKey(), event.getValue());
        // }
        // tsn.complete();
        // }
        // setTrowable2Transaction(ex);
        // Cat.getProducer().logError(ex);
        // httpTransaction.complete();
        // exchange.getAttributes().put(Constants.CAT_TRANSACTION, new ArrayList<>());
        // } else {
        // Transaction transation = (Transaction) exchange.getAttributes().get(Constants.TRANSACTION);
        // if (null != transation && !transation.isCompleted()) {
        // setTrowable2Transaction(ex);
        // Cat.getProducer().logError(ex);
        // transation.setStatus(ex);
        // transation.complete();
        // }
        // exchange.getAttributes().remove(Constants.TRANSACTION);
        // exchange.getAttributes().put(Constants.CAT_TRANSACTION, new ArrayList<>());
        // }
        // }
    }

    private void setTrowable2Transaction(Throwable ex) {
        if (ex instanceof BaseException) {
            BaseException exception = (BaseException)ex;
            setExeptionTransaction(exception);
        } else {
            BaseException exception = new BaseException(ex);
            setExeptionTransaction(exception);
        }
    }

    /**
     * 设置错误信息
     *
     * @param exception
     */
    private void setExeptionTransaction(BaseException exception) {
        // Transaction t = Cat.newTransaction("Gateway.exception", exception.getErrorCode() + ":" +
        // exception.getErrorMessage());
        // t.addData(exception.getErrorCode(), exception.getErrorMessage());
        // t.setStatus("0");
        // t.complete();
    }

    // private String getTransaction(String actionId, Map<String, Object> bodyMap) {
    // Map<String, Object> header = (Map<String, Object>) bodyMap.get("header");
    // if (null != header) {
    // String version = (String) header.get(Constants.VERSION);
    // Map<Object, Object> map = accessCacheDataSyncHandler.getAccessParamMap().get(Constants.OPEN_GATE_CACHE_NAME +
    // "_" + Constants.API_INFO_PREFIX + actionId + Constants.BOTTOM_LINE + version);
    // if (null != map) {
    // return "[" + actionId + "]" + map.get("apiName");
    // } else {
    // return actionId;
    // }
    // } else {
    // return actionId;
    // }
    // }

    // @After("routeFilterPointCut()")
    // public void afterPointCut(JoinPoint joinPoint) {
    // if (joinPoint.getArgs()[0] instanceof ServerWebExchange) {
    // ServerWebExchange exchange = (ServerWebExchange) joinPoint.getArgs()[0];
    // List<CatTransation> transactions = (List<CatTransation>) exchange.getAttributes().get(Constants.CAT_TRANSACTION);
    // if (null != transactions && !transactions.isEmpty()) {
    // catTransactionComplete(exchange, transactions);
    // }
    // }
    // }

    // private void catTransactionComplete(ServerWebExchange exchange, List<CatTransation> transactions) {
    // String logId = (String) exchange.getAttributes().get(Constants.GLOBALLOGID);
    // Cat.getProducer().setCustomizeMsgId(logId.substring(logId.lastIndexOf("-") + 1));
    // CatTransation httpCatTranstion = transactions.remove(0);
    // Transaction httpTransaction = Cat.getProducer().newTransaction(httpCatTranstion.getTransationName(),
    // httpCatTranstion.getDesc());
    // httpTransaction.setStatus("0");
    // Transaction transaction = Cat.getProducer().newTransaction("Http.Info", logId);
    // transaction.setStatus("0");
    // transaction.complete();
    // for (CatTransation transation : transactions) {
    // Transaction tsn = Cat.newTransaction(transation.getTransationName(), transation.getDesc());
    // tsn.setStatus(transation.getStatus());
    // Map<String, String> events = transation.getEvents();
    // for (Map.Entry<String, String> event : events.entrySet()) {
    // Cat.logEvent(event.getKey(), event.getValue());
    // }
    // tsn.complete();
    // }
    // httpCatTranstion.setStatus("0");
    // httpTransaction.complete();
    // exchange.getAttributes().put(Constants.CAT_TRANSACTION, new ArrayList<>());
    // }

}
